use criterion::{black_box, criterion_group, criterion_main, Criterion};
use codegraph_parser::dpml::*;

fn create_large_dpml_document() -> String {
    let mut doc = String::new();
    doc.push_str("<prompt>\n");
    
    // 创建大量嵌套元素
    for i in 0..100 {
        doc.push_str(&format!(r#"
  <thinking type="analysis-{}" priority="{}">
    # 问题分析 {}
    这是一个**数据处理**问题，需要考虑：
    1. 数据格式转换
    2. 性能优化
    3. 错误处理
    
    参考资源：@file://document-{}.md
    相关术语：#数据处理 #性能优化 #错误处理
    
    <concept id="arch-{}" domain="backend">
      ## 架构概念 {}
      使用微服务架构设计
      
      <detail level="high">
        详细的架构说明...
        更多内容...
      </detail>
    </concept>
  </thinking>
"#, i, i % 3, i, i, i, i));
    }
    
    // 添加一些自闭合元素
    for i in 0..50 {
        doc.push_str(&format!(r#"  <resource type="reference" src="docs/api-{}.md" priority="{}" />
"#, i, i % 5));
    }
    
    // 添加命名空间元素
    for i in 0..20 {
        doc.push_str(&format!(r#"
  <store:execution id="op-{}">
    <content>操作内容 {}</content>
    <process>
      # 处理流程 {}
      1. 步骤一
      2. 步骤二
      3. 步骤三
    </process>
    <rule>
      规则 {}: 必须满足条件
    </rule>
  </store:execution>
"#, i, i, i, i));
    }
    
    doc.push_str("</prompt>");
    doc
}

fn benchmark_dpml_parsing(c: &mut Criterion) {
    let large_doc = create_large_dpml_document();
    
    c.bench_function("dpml_parse_large_document", |b| {
        b.iter(|| {
            let mut parser = DpmlParser::new().unwrap();
            let doc = parser.parse(black_box(&large_doc)).unwrap();
            black_box(doc);
        });
    });
}

fn benchmark_element_extraction(c: &mut Criterion) {
    let large_doc = create_large_dpml_document();
    let mut parser = DpmlParser::new().unwrap();
    let doc = parser.parse(&large_doc).unwrap();
    
    c.bench_function("dpml_extract_elements", |b| {
        b.iter(|| {
            let elements = doc.elements();
            black_box(elements);
        });
    });
}

fn benchmark_resource_references(c: &mut Criterion) {
    let large_doc = create_large_dpml_document();
    let mut parser = DpmlParser::new().unwrap();
    let doc = parser.parse(&large_doc).unwrap();
    
    c.bench_function("dpml_extract_resource_references", |b| {
        b.iter(|| {
            let refs = doc.resource_references();
            black_box(refs);
        });
    });
}

fn benchmark_term_references(c: &mut Criterion) {
    let large_doc = create_large_dpml_document();
    let mut parser = DpmlParser::new().unwrap();
    let doc = parser.parse(&large_doc).unwrap();
    
    c.bench_function("dpml_extract_term_references", |b| {
        b.iter(|| {
            let refs = doc.term_references();
            black_box(refs);
        });
    });
}

fn benchmark_tag_search(c: &mut Criterion) {
    let large_doc = create_large_dpml_document();
    let mut parser = DpmlParser::new().unwrap();
    let doc = parser.parse(&large_doc).unwrap();
    
    c.bench_function("dpml_find_elements_by_tag", |b| {
        b.iter(|| {
            let thinking_elements = doc.find_elements_by_tag(black_box("thinking"));
            black_box(thinking_elements);
        });
    });
}

fn benchmark_query_execution(c: &mut Criterion) {
    let large_doc = create_large_dpml_document();
    
    c.bench_function("dpml_query_execution", |b| {
        b.iter(|| {
            let mut parser = DpmlParser::new().unwrap();
            let query_str = r#"(element (paired_element (start_tag (tag_name) @tag)))"#;
            let result = parser.query(black_box(&large_doc), black_box(query_str)).unwrap();
            black_box(result);
        });
    });
}

criterion_group!(
    benches,
    benchmark_dpml_parsing,
    benchmark_element_extraction,
    benchmark_resource_references,
    benchmark_term_references,
    benchmark_tag_search,
    benchmark_query_execution
);
criterion_main!(benches);
